package com.xiaoyuan.minicore.aop;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.xiaoyuan.minicore.aop.annotation.Aspect;
import com.xiaoyuan.minicore.core.ClassHelper;
import com.xiaoyuan.minicore.ioc.BeanHelper;
import com.xiaoyuan.minicore.ioc.annotation.Bean;
import com.xiaoyuan.minicore.util.StringUtil;
import org.apache.commons.collections.CollectionUtils;

/**
 * @Auther: xiaoyuan
 * @Date: 2020/4/29
 * @Description:
 */
public class AOPHelper {


    //@bean注解的class被哪些handler给AOP住
    private static final Map<Class, Set<Class>> aspectMap = new HashMap<Class, Set<Class>>();

    public static void init() {
        try {
            // 获取带有 @Aspect 注解的类（切面类）
            List<Class<?>> aspectClassList = ClassHelper.getClassListByAnnotation(Aspect.class);
            // 遍历所有切面类
            for (Class<?> aspectClass : aspectClassList) {
                if(!Handler.class.isAssignableFrom(aspectClass) || Handler.class.equals(aspectClass)){
                    //不继承handler的切面没用
                    continue;
                }
                // 获取 @Aspect 注解中的属性值
                Aspect aspect = aspectClass.getAnnotation(Aspect.class);
                String pkg = aspect.pkg(); // 包名
                String cls = aspect.cls(); // 类名
                // 初始化目标类列表
                List<Class<?>> targetClassList = new ArrayList<Class<?>>();
                if (StringUtil.isNotEmpty(pkg) && StringUtil.isNotEmpty(cls)) {
                    // 如果包名与类名均不为空，则添加指定类
                    targetClassList.add(Class.forName(pkg + "." + cls));
                } else {
                    // 否则（包名不为空）添加该包名下所有类
                    targetClassList.addAll(ClassHelper.getClassListByPackage(pkg));
                }
                // 遍历目标类列表
                if (CollectionUtils.isNotEmpty(targetClassList)) {
                    for (Class<?> targetClass : targetClassList) {
                       if(targetClass.isAnnotationPresent(Bean.class)){
                           if(getSet(targetClass)==null){
                               aspectMap.put(targetClass,new HashSet<>());
                           }
                           getSet(targetClass).add(aspectClass);
                       }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static  Map<Class, Set<Class>> getAspectMap() {
        return aspectMap;
    }

    @SuppressWarnings("unchecked")
    public static Set<Class> getSet(Class cls) {
        return aspectMap.get(cls);
    }
}
